﻿using Microsoft.VisualBasic;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Diagnostics;
using IKEYCOMLib;

namespace Panchina.Security.IKey1000
{
    public class IKeyapi
    {
        public static byte[] serialNum = new byte[8];
        public static string friendlyName;
        public static long capability;
        public static long memSize;
        public static SAccessInfo accessInfo;
        public static SVersionInfo versionInfo;
        public static SSysInfo sysInfo;
        public static SFileInfo fileInfo;

        public static SDirInfo dirInfo;

        public const int IKEY_MAX_LEVEL = 0x8;
        public const int IKEY_NULL = 0x0;

        public const int IKEY_API_VERSION = 0x200;
        public const int IKEY_OPEN_NEXT = 0x0;
        public const int IKEY_OPEN_FIRST = 0x1;
        public const int IKEY_OPEN_CURRENT = 0x2;
        public const int IKEY_OPEN_SPECIFIC = 0x3;
        public const int IKEY_OPEN_MASK = 0x7;
        public const int IKEY_OPEN_BY_NAME = 0x100;

        public const int IKEY_OPEN_BY_GUID = 0x200;
        public const int IKEY_CONFIG_DES_KEY_SIZE = 0x1;

        public const int IKEY_CONFIG_RSA_MOD_SIZE = 0x2;
        public const int IKEY_PROP_CAPABILITIES = 0x0;
        public const int IKEY_PROP_MEM_SIZE = 0x1;
        public const int IKEY_PROP_ROOT_ACCESSINFO = 0x2;
        public const int IKEY_PROP_ACCESSINFO = 0x3;
        public const int IKEY_PROP_APP_NAME = 0x4;
        public const int IKEY_PROP_APP_GUID = 0x5;
        public const int IKEY_PROP_VERSIONINFO = 0x6;
        public const int IKEY_PROP_SERNUM = 0x7;
        public const int IKEY_PROP_LED_ON = 0x8;
        public const int IKEY_PROP_LED_OFF = 0x9;
        public const int IKEY_PROP_CONFIGURATION = 0xa;

        public const int IKEY_PROP_FRIENDLY_NAME = 0xb;
        public const int IKEY_ROOT_DIR = 0x0;
        public const int IKEY_INDEX_FILE = 0xffff;

        public const int IKEY_TOKEN_NAME_FILE = 0xfffe;
        public const int IKEY_DIR_BY_ID = 0x100;
        public const int IKEY_DIR_BY_LONG_ID = 0x200;
        public const int IKEY_DIR_BY_NAME = 0x300;
        public const int IKEY_DIR_BY_GUID = 0x400;

        public const int IKEY_DIR_BY_MASK = 0xf00;
        public const int IKEY_FILETYPE_UNUSED = 0x0;
        public const int IKEY_FILETYPE_DIR = 0x1;
        public const int IKEY_FILETYPE_DATA = 0x2;
        public const int IKEY_FILETYPE_COUNTER = 0x3;
        public const int IKEY_FILETYPE_KEY = 0x4;

        public const int IKEY_FILETYPE_UNKNOWN = 0xff;
        public const int IKEY_ACCESS_ANYONE = 0x0;
        public const int IKEY_ACCESS_USER = 0x1;
        public const int IKEY_ACCESS_OFFICER = 0x2;
        public const int IKEY_ACCESS_APP = 0x3;

        public const int IKEY_ACCESS_NONE = 0x7;
        public const int IKEY_ACCESS_READ = 0x1;
        public const int IKEY_ACCESS_WRITE = 0x2;

        public const int IKEY_ACCESS_CRYPT = 0x4;
        public const int IKEY_CAPS_MD5HMAC = 0x1;
        public const int IKEY_CAPS_MD5XOR = 0x2;
        public const int IKEY_CAPS_MD5CHAP = 0x4;
        public const int IKEY_CAPS_DES = 0x8;

        public const int IKEY_CAPS_APPAUTH = 0x20;
        public const int IKEY_DIR_FROM_MF = 0x0;
        public const int IKEY_DIR_FROM_CUR_DF = 0x10;

        public const int IKEY_DIR_TO_PARENT = 0x20;
        public const int IKEY_FILE_READ = 0x10;
        public const int IKEY_FILE_WRITE = 0x20;

        public const int IKEY_FILE_CRYPT = 0x40;

        public const int IKEY_CREATE_AUTO_ID = 0x10000;

        public const int IKEY_DELETE_RECURSIVE = 0x10000;
        public const int IKEY_VERIFY_USER_PIN = 0x0;
        public const int IKEY_VERIFY_SO_PIN = 0x1;

        public const int IKEY_VERIFY_APPKEY = 0x2;
        public const int IKEY_CHANGE_USER_PIN = 0x0;
        public const int IKEY_UNBLOCK_USER_PIN = 0x1;
        public const int IKEY_CHANGE_SO_PIN = 0x2;
        public const int IKEY_CHANGE_APP_KEY = 0x3;

        public const int IKEY_CHANGE_MASK = 0xf;
        public const int IKEY_SCOPE_MF = 0x0;

        public const int IKEY_SCOPE_DF = 0x1;
        public const int IKEY_HASH_MD5_XOR = 0x0;
        public const int IKEY_HASH_MD5_HMAC = 0x1;
        public const int IKEY_HASH_MD5_CHAP = 0x2;
        public const int IKEY_HASH_DES_MAC = 0x10;

        public const int IKEY_HASH_TYPE_MASK = 0xff;
        public const int IKEY_CRYPT_DES = 0x0;

        public const int IKEY_CRYPT_TYPE_MASK = 0xff;
        public const int IKEY_GENKEY_ENCRYPT = 0x100;
        public const int IKEY_GENKEY_CREATE = 0x200;
        public const int IKEY_DES_ENCRYPT = 0x80;

        public const int IKEY_DES_DECRYPT = 0x40;
        public const int RB_SUCCESS = 0x0;
        public const long RB_CANNOT_OPEN_DRIVER = 0x80100001;
        public const long RB_INVALID_DRVR_VERSION = 0x80100002;
        public const int RB_INVALID_COMMAND = 0x3;
        public const int RB_ACCESS_DENIED = 0x4;
        public const int RB_ALREADY_ZERO = 0x5;
        public const int RB_UNIT_NOT_FOUND = 0x6;
        public const int RB_DEVICE_REMOVED = 0x7;
        public const int RB_COMMUNICATIONS_ERROR = 0x8;
        public const int RB_DIR_NOT_FOUND = 0x9;
        public const long RB_FILE_NOT_FOUND = 0x8010000a;
        public const int RB_MEM_CORRUPT = 0xb;
        public const int RB_INTERNAL_HW_ERROR = 0xc;
        public const int RB_INVALID_RESP_SIZE = 0xd;
        public const int RB_PIN_EXPIRED = 0xe;
        public const int RB_ALREADY_EXISTS = 0xf;
        public const int RB_NOT_ENOUGH_MEMORY = 0x10;
        public const int RB_INVALID_PARAMETER = 0x11;
        public const int RB_ALIGNMENT_ERROR = 0x12;
        public const int RB_INPUT_TOO_LONG = 0x13;
        public const int RB_INVALID_FILE_SELECTED = 0x14;
        public const int RB_DEVICE_IN_USE = 0x15;
        public const int RB_INVALID_API_VERSION = 0x16;
        public const int RB_TIME_OUT_ERROR = 0x17;
        public const int RB_ITEM_NOT_FOUND = 0x18;
        public const int RB_COMMAND_ABORTED = 0x19;
        public const int RB_INVALID_STATUS = 0xff;
        public const long RB_LIBRARY_NOT_FOUND = 0x80104001;
        public const long RB_LIBRARY_OBSOLETE = 0x80104002;

        public const long RB_LIBRARY_MISMATCH = 0x80104003;
        public struct AccessType
        {
            /// <summary>
            /// 读取
            /// </summary>
            public byte Read;
            /// <summary>
            /// 写入
            /// </summary>
            public byte Write;
            public byte Crypt;
        }

        public struct ReturnStatus
        {
            public string Message;
            public long Code;
        }

        public static void StringToByteArray(ref byte[] hexByte, string str, long size)
        {
            long i = 0;
            string s = null;

            s = str;
            for (i = 0; i <= size - 1; i++)
            {
                if (Strings.Len(s) != 0)
                {
                    hexByte[i] = Convert.ToByte(Strings.Asc(s));
                    s = Strings.Right(s, Strings.Len(s) - 1);
                }
                else
                {
                    hexByte[i] = 0;
                }
            }
        }

        public static byte[] StrToByteArray(string str)
        {
            return System.Text.Encoding.GetEncoding("gb2312").GetBytes(str);
        }

        public static void ByteArrayToString(ref string str, byte[] hexByte, long size)
        {
            long i = 0;

            str = "";
            for (i = 0; i <= size - 1; i++)
            {
                if (Convert.ToInt32(hexByte[i]) != 0)
                {
                    str = str + Strings.Chr(Convert.ToInt32(hexByte[i]));
                }
            }
        }

        public static string ByteArrayToStr(byte[] buffer)
        {
            return System.Text.Encoding.GetEncoding("gb2312").GetString(buffer);
        }

        public static void HexToString(byte[] hexByte, ref string str, long size)
        {
            byte b = 0;
            long i = 0;

            for (i = size - 1; i >= 0; i += -1)
            {
                b = Convert.ToByte(Math.Truncate(Convert.ToDouble(hexByte[i]) / 16));
                if (b > 9)
                {
                    str = str + Strings.Chr(b + Strings.Asc("A") - 10);
                }
                else
                {
                    str = str + Strings.Chr(b + Strings.Asc("0"));
                }

                b = Convert.ToByte(hexByte[i] % 16);
                if (b > 9)
                {
                    str = str + Strings.Chr(b + Strings.Asc("A") - 10);
                }
                else
                {
                    str = str + Strings.Chr(b + Strings.Asc("0"));
                }
            }
        }

        public static void StringToHex(byte[] hexByte, string str, long size)
        {
            byte b = 0;
            long i = 0;
            string s = null;

            for (i = 0; i <= size - 1; i++)
            {
                hexByte[i] = 0;
            }

            if (Strings.Left(str, 2) == "&H")
            {
                s = Strings.UCase(Strings.Right(str, Strings.Len(str) - 2));
            }
            else
            {
                s = Strings.UCase(str);
            }

            for (i = 0; i <= size - 1; i++)
            {
                if (Strings.Len(s) == 0)
                {
                    break; // TODO: might not be correct. Was : Exit For
                }

                b = Convert.ToByte(Strings.Asc(s));
                if (b > 64 & b < 71)
                {
                    hexByte[i] = Convert.ToByte(b - 65 + 10);
                }
                else if (b > 47 & b < 58)
                {
                    hexByte[i] = Convert.ToByte(b - 48);
                }

                hexByte[i] = Convert.ToByte(hexByte[i] * 16);
                s = Strings.Right(s, Strings.Len(s) - 1);
                if (Strings.Len(s) == 0)
                {
                    break; // TODO: might not be correct. Was : Exit For
                }

                b = Convert.ToByte(Strings.Asc(s));
                if (b > 64 & b < 71)
                {
                    hexByte[i] = Convert.ToByte(b - 65 + 10 + hexByte[i]);
                }
                else if (b > 47 & b < 58)
                {
                    hexByte[i] = Convert.ToByte(b - 48 + hexByte[i]);
                }

                s = Strings.Right(s, Strings.Len(s) - 1);
                if (Strings.Len(s) == 0)
                {
                    break; // TODO: might not be correct. Was : Exit For
                }
            }
        }

        public static void ByteArrayToLong(long l, byte[] ba)
        {
            string s = null;
            string m = null;

            s = "&H";

            m = Conversion.Hex(ba[3]);
            if (Strings.Len(m) < 2)
            {
                s = s + "0";
            }
            s = s + m;

            m = Conversion.Hex(ba[2]);
            if (Strings.Len(m) < 2)
            {
                s = s + "0";
            }
            s = s + m;

            m = Conversion.Hex(ba[1]);
            if (Strings.Len(m) < 2)
            {
                s = s + "0";
            }
            s = s + m;

            m = Conversion.Hex(ba[0]);
            if (Strings.Len(m) < 2)
            {
                s = s + "0";
            }
            s = s + m;

            l = Convert.ToInt64(Conversion.Val(s));
        }

        public static void LongToByteArray(byte[] ba, long l)
        {
            string s = null;
            string m = null;

            ba[0] = 0;
            ba[1] = 0;
            ba[2] = 0;
            ba[3] = 0;
            s = Conversion.Hex(l);

            m = Strings.Right(s, 2);
            ba[0] = Convert.ToByte(Conversion.Val("&H" + m));

            if (Strings.Len(s) > 2)
            {
                s = Strings.Left(s, Strings.Len(s) - 2);
                m = Strings.Right(s, 2);
                ba[1] = Convert.ToByte(Conversion.Val("&H" + m));
            }

            if (Strings.Len(s) > 2)
            {
                s = Strings.Left(s, Strings.Len(s) - 2);
                m = Strings.Right(s, 2);
                ba[2] = Convert.ToByte(Conversion.Val("&H" + m));
            }

            if (Strings.Len(s) > 2)
            {
                s = Strings.Left(s, Strings.Len(s) - 2);
                m = Strings.Right(s, 2);
                ba[3] = Convert.ToByte(Conversion.Val("&H" + m));
            }
        }

    }
}
